<template>
  <Select
    :value="getVal"
    filterable
    v-bind="$attrs"
    :multiple="props.multiple"
    @change="handleChange"
  >
    <Option
      v-for="item in options"
      :key="item.label"
      :label="item[$props.fieldNames.label]"
      :value="item[$props.fieldNames.value]"
      v-bind="item"
    />
  </Select>
</template>

<script setup name="basic-select">
import { ref, watchEffect, unref, computed, watch } from 'vue'
import { Select, Option } from 'element-ui'
import { isFunction } from 'lodash-es'

const props = defineProps({
  value: {
    type: [String, Array, Number],
    default: ''
  },
  options: {
    type: Array,
    default: () => []
  },
  fieldNames: {
    type: Object,
    default: () => ({ label: 'label', value: 'value' })
  },
  labelInValue: {
    type: Boolean,
    default: false
  },
  showTotalOptionItem: {
    type: Boolean,
    default: false
  },
  totalOptionItemText: {
    type: String,
    default: '全部'
  },
  formatData: {
    type: Function,
    default: null
  },
  multiple: {
    type: Boolean,
    default: false
  }
})
const emit = defineEmits(['options-change', 'update:value'])

const val = ref(props.value)
const options = ref([])

const getVal = computed(() => {
  if (props.labelInValue && unref(val)?.length) {
    if (props.multiple) {
      return unref(val).map(item => item[props.fieldNames.value])
    }
    return unref(val)[0][props.fieldNames.value]
  }
  return unref(val) ?? ''
})

watch(
  () => props.value,
  (value) => (val.value = value),
  { immediate: true }
)

watchEffect(() => {
  if (props.formatData && isFunction(props.formatData)) {
    options.value = props.formatData(props.options)
  } else {
    options.value = props.options
  }

  const { fieldNames, totalOptionItemText } = props
  if (props.showTotalOptionItem) {
    const result = unref(options).find(item => (item[fieldNames.value] === -1))
    !result && options.value.unshift({ [fieldNames.label]: totalOptionItemText, [fieldNames.value]: -1 })
  }
})

function handleChange(e) {
  val.value = e
  if (props.labelInValue) {
    e = unref(options).filter(item => item[props.fieldNames.value] === e)
  }
  emit('options-change', e)
  emit('update:value', e)
}
</script>

<style lang="scss">
::v-deep {
  .el-select {
    width: 100% !important;
  }
}
</style>
